﻿#region Header

/***************************************************************************
Author : Krishan Kaliraman (www.sharedwith.me)  Date: 1 Aug 2012
***************************************************************************/

#endregion Header
using System;
using System.Configuration;
using System.Collections.Generic;
using System.Net;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;

namespace Common
{
    public class Sprint
    {
        private  string WiqlQueryForCommittedWorkItemsForSprint = @"SELECT [System.Id],[System.AssignedTo], [System.WorkItemType], [System.State], [System.AssignedTo], [System.Title] FROM WorkItems WHERE 
                                    [System.TeamProject] = '"+ StaticItems.TFSProjectName+ "' and [System.IterationPath]= '" + StaticItems.CurrentSprintIteration + "' and ( [System.WorkItemType]= 'Bug' or [System.WorkItemType]= 'Product Backlog Item' or [System.WorkItemType]= 'Impediment' ) " +
                                    " and ( [System.State]= 'Committed' or [System.State]= 'Done' or [System.State]= 'Open'  or [System.State]= 'Closed') and [System.NodeName]='" + StaticItems.NodeName + "' ORDER BY [System.WorkItemType], [System.Id]";
        
        public List<Activity> AllCommittedWorkItemsForSprint = new List<Activity>();

        public List<Activity> AllRemainingTasksForSprint = new List<Activity>();

        public Sprint()
        {
        }

        public void SendDailyStatusEmail(QuoteOfTheDay quote=null)
        {
            FillCurrentSprintWorkItems();
            FillCurrentSprintCommittedWorkItemsWithRespectiveRemainingTasks();
            DailyStatusEmail.SendDailyStatusEmail(AllCommittedWorkItemsForSprint,quote);
        }

        public void FillCurrentSprintWorkItems()
        {
            WorkItemCollection workItems = Helper.GetWorkItems(WiqlQueryForCommittedWorkItemsForSprint);
            foreach (WorkItem workItem in workItems)
            {
                var newActivity = new Activity(workItem);
                AllCommittedWorkItemsForSprint.Add(newActivity);
            }
        }

        public void FillAllCurrentSprintWorkItemsWithTasks(string activityTypes)
        {
            FillCurrentSprintWorkItems();
            if (AllCommittedWorkItemsForSprint.Count == 0)
                return;
            string[] allActivityTypes = activityTypes.Split(new string[1] {","}, StringSplitOptions.None);
            foreach (var activityType in allActivityTypes)
            {
                string wiqlQuery=MakeWiqlQuery( activityType );
                WorkItemCollection workItems = Helper.GetWorkItems(wiqlQuery);
                foreach (WorkItem workItem in workItems)
                {
                    if (Helper.IsWorkItemInProgressOrToDo(workItem))
                    {
                        var newActivity = new Activity(workItem, activityType);
                        AllRemainingTasksForSprint.Add(newActivity);
                    }
                }
            }
            FillUnknownTasksForSprint();
            int x = AllRemainingTasksForSprint.Count;
            int y = totalcount;
            FillCurrentSprintCommittedWorkItemsWithRespectiveRemainingTasks();
        }

        public void FillAllCurrentSprintWorkItemsWithTasks(string activityTypes,NetworkCredential networkCredential)
        {
            FillCurrentSprintWorkItems();
            if (AllCommittedWorkItemsForSprint.Count == 0)
                return;
            string[] allActivityTypes = activityTypes.Split(new string[1] { "," }, StringSplitOptions.None);
            foreach (var activityType in allActivityTypes)
            {
                string wiqlQuery = MakeWiqlQuery(activityType);
                WorkItemCollection workItems = Helper.GetWorkItems(wiqlQuery,networkCredential);
                foreach (WorkItem workItem in workItems)
                {
                    if (Helper.IsWorkItemInProgressOrToDo(workItem))
                    {
                        var newActivity = new Activity(workItem, activityType);
                        AllRemainingTasksForSprint.Add(newActivity);
                    }
                }
            }
            FillUnknownTasksForSprint();
            int x = AllRemainingTasksForSprint.Count;
            int y = totalcount;
            FillCurrentSprintCommittedWorkItemsWithRespectiveRemainingTasks();
        }


        public List<ChartActivity> FillAllCurrentSprintCommittedChartActivities(string activityTypes)
        {
            FillAllCurrentSprintWorkItemsWithTasks(activityTypes);
            string[] allActivityTypes = activityTypes.Split(new string[1] { "," }, StringSplitOptions.None);
            List<ChartActivity> allCommittedChartActivities = new List<ChartActivity>();
            foreach (var activity in AllCommittedWorkItemsForSprint)
            {
                ChartActivity newChartActivity = new ChartActivity(allActivityTypes, activity);
                allCommittedChartActivities.Add(newChartActivity);
            }
            return allCommittedChartActivities;
        }

        public List<ChartActivity> FillAllCurrentSprintCommittedChartActivities(string activityTypes, NetworkCredential networkCredential)
        {
            FillAllCurrentSprintWorkItemsWithTasks(activityTypes);
            string[] allActivityTypes = activityTypes.Split(new string[1] { "," }, StringSplitOptions.None);
            List<ChartActivity> allCommittedChartActivities = new List<ChartActivity>();
            foreach (var activity in AllCommittedWorkItemsForSprint)
            {
                ChartActivity newChartActivity = new ChartActivity(allActivityTypes, activity);
                allCommittedChartActivities.Add(newChartActivity);
            }
            return allCommittedChartActivities;
        }

        public static DiscussionActivity ReturnDiscussionActivity(string activityId)
        {
            string query =
                   @"SELECT [System.Id],[System.AssignedTo], [System.WorkItemType], [System.State], [System.AssignedTo], [System.Title] FROM WorkItems WHERE 
                                    [System.TeamProject] = '"+ StaticItems.TFSProjectName+ "' and [System.Id] = '" + activityId + "' ORDER BY [System.WorkItemType], [System.Id]";

            WorkItemCollection workItems = Helper.GetWorkItems(query);
            DiscussionActivity newDiscussionActivity = new DiscussionActivity(workItems[0]);
            return newDiscussionActivity;
        }

        public static DiscussionActivity ReturnDiscussionActivity(string activityId, NetworkCredential networkCredentials)
        {
            string query =
                   @"SELECT [System.Id],[System.AssignedTo], [System.WorkItemType], [System.State], [System.AssignedTo], [System.Title] FROM WorkItems WHERE 
                                    [System.TeamProject] = '"+ StaticItems.TFSProjectName+ "' and [System.Id] = '" + activityId + "' ORDER BY [System.WorkItemType], [System.Id]";

            WorkItemCollection workItems = Helper.GetWorkItems(query,networkCredentials);
            DiscussionActivity newDiscussionActivity = new DiscussionActivity(workItems[0]);
            return newDiscussionActivity;
        }

        #region Private Methods

        private string MakeWiqlQuery(string activitType)
        {
            string wiqlQuery=@"SELECT * FROM WorkItems WHERE [System.TeamProject] = '"+ StaticItems.TFSProjectName+ "' and [System.WorkItemType]='Task' "+ MakeCondition() +" and [Activity] ='" + activitType + "' and [System.NodeName]='" + StaticItems.NodeName + "' ORDER BY [System.WorkItemType], [System.Id]";
            return wiqlQuery;
        }

        private int totalcount=0;
        private string MakeCondition()
        {
            string innerConditionForTaskIds = string.Empty ;
            if (AllCommittedWorkItemsForSprint.Count==0 || AllRemainingTasksForSprint.Count==0)
            {
                return innerConditionForTaskIds;
            }
            
            innerConditionForTaskIds += " and ( ";
            int count = 0;
            foreach (var committedWorkItem in AllCommittedWorkItemsForSprint)
            {
                int innerCount = 0;
                count = count + 1;
                if (count == AllCommittedWorkItemsForSprint.Count && committedWorkItem.IdOfAlllinkedWorkItems.Count==0)
                {
                    if(innerConditionForTaskIds.EndsWith("or"))
                    {
                       innerConditionForTaskIds= innerConditionForTaskIds.Remove(innerConditionForTaskIds.Length - 2, 2);
                    }
                }
                foreach (var taskId in committedWorkItem.IdOfAlllinkedWorkItems )
                {
                    innerCount = innerCount + 1;
                    if (count == AllCommittedWorkItemsForSprint.Count && innerCount == committedWorkItem.IdOfAlllinkedWorkItems.Count)
                    {
                        innerConditionForTaskIds = innerConditionForTaskIds+ " [System.Id]='" +taskId + "' ";
                    }
                    else
                    {
                        innerConditionForTaskIds =innerConditionForTaskIds+ " [System.Id]='" + taskId + "' or";
                    }
                }
            }
            innerConditionForTaskIds += " )";
            
            return innerConditionForTaskIds;
        }

        private void FillCurrentSprintCommittedWorkItemsWithRespectiveRemainingTasks()
        {
            foreach (var committedActivity in AllCommittedWorkItemsForSprint)
            {
                foreach (var childLinkedWorkItemId in committedActivity.IdOfAlllinkedWorkItems  )
                {
                    foreach (var currentTask in AllRemainingTasksForSprint)
                    {
                        if (childLinkedWorkItemId == currentTask.Id)
                        {
                            committedActivity.LinkedChildWorkItems.Add(currentTask);
                        }
                    }
                }
                
            }
        }

        private void FillUnknownTasksForSprint()
        {
            WorkItemCollection workItems = Helper.GetWorkItems(MakeWiqlQuery(string.Empty));
            foreach (WorkItem workItem in workItems)
            {
                if (Helper.IsWorkItemInProgressOrToDo(workItem))
                {
                    var newActivity = new Activity(workItem, "");
                    AllRemainingTasksForSprint.Add(newActivity);
                }
            }
        }

        #endregion 
        
    
        public static DiscussionActivity SubmitDiscussionItem(DiscussionItem discussionItem)
        {
            string query =
                    @"SELECT [System.Id],[System.AssignedTo], [System.WorkItemType], [System.State], [System.AssignedTo], [System.Title] FROM WorkItems WHERE 
                                    [System.TeamProject] = '" + StaticItems.TFSProjectName + "' and [System.Id] = '" + discussionItem.DiscussionActivityId + "' ORDER BY [System.WorkItemType], [System.Id]";

            WorkItemCollection workItems = Helper.GetWorkItems(query);
            DiscussionActivity newDiscussionActivity = new DiscussionActivity();
            newDiscussionActivity.WorkItem = workItems[0];
            newDiscussionActivity = newDiscussionActivity.SubmitDiscussionItem(discussionItem);
            return newDiscussionActivity;
        }

        public static DiscussionActivity UploadAttachmentAndEnterDiscussionItemToDiscussionActivity(string filePath, string comment, DiscussionItem discussionItem)
        {
            string query =
                   @"SELECT [System.Id],[System.AssignedTo], [System.WorkItemType], [System.State], [System.AssignedTo], [System.Title] FROM WorkItems WHERE 
                                    [System.TeamProject] = '"+ StaticItems.TFSProjectName+ "' and [System.Id] = '" + discussionItem.DiscussionActivityId + "' ORDER BY [System.WorkItemType], [System.Id]";

            WorkItemCollection workItems = Helper.GetWorkItems(query); 
            DiscussionActivity newDiscussionActivity = new DiscussionActivity();
            newDiscussionActivity.WorkItem = workItems[0];
            newDiscussionActivity = newDiscussionActivity.UploadAttachmentAndDiscussionItemToDiscussionActivity(filePath, comment , discussionItem);
            return newDiscussionActivity;
        }

        public static DiscussionActivity UploadAttachmentToDiscussionActivity(string filePath, string comment, string activiTyId)
        {
            string query =
                   @"SELECT [System.Id],[System.AssignedTo], [System.WorkItemType], [System.State], [System.AssignedTo], [System.Title] FROM WorkItems WHERE 
                                    [System.TeamProject] = '" + StaticItems.TFSProjectName + "' and [System.Id] = '" + activiTyId + "' ORDER BY [System.WorkItemType], [System.Id]";

            WorkItemCollection workItems = Helper.GetWorkItems(query);
            DiscussionActivity newDiscussionActivity = new DiscussionActivity();
            newDiscussionActivity.WorkItem = workItems[0];
            newDiscussionActivity = newDiscussionActivity.UploadAttachmentToDiscussionActivity(filePath, comment);
            return newDiscussionActivity;
        }

        public static DiscussionActivity UploadAttachmentAndEnterDiscussionItemToDiscussionActivity(string filePath, string fileComment, DiscussionItem discussionItem, NetworkCredential networkCredential)
        {
            string query =
                   @"SELECT [System.Id],[System.AssignedTo], [System.WorkItemType], [System.State], [System.AssignedTo], [System.Title] FROM WorkItems WHERE 
                                    [System.TeamProject] = '" + StaticItems.TFSProjectName + "' and [System.Id] = '" + discussionItem.DiscussionActivityId + "' ORDER BY [System.WorkItemType], [System.Id]";

            WorkItemCollection workItems = Helper.GetWorkItems(query);
            DiscussionActivity newDiscussionActivity = new DiscussionActivity();
            newDiscussionActivity.WorkItem = workItems[0];
            newDiscussionActivity = newDiscussionActivity.UploadAttachmentAndDiscussionItemToDiscussionActivity(filePath, fileComment, discussionItem);
            return newDiscussionActivity;
        }
    }
}
